package com.zbf.config;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: LCG
 * 作者: LCG
 * 日期: 2021/6/25  16:01
 * 描述:
 */
@Component
public class LoginFilter implements GlobalFilter {

    @Autowired
    private NoLoginPathConfig noLoginPathConfig;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        //获取当前的请求路径
        String path = exchange.getRequest().getURI().getPath();

        boolean contains = noLoginPathConfig.getPath().contains(path);
        if(contains){
            //不需要登录直接放行
            return chain.filter(exchange);
        }else{
            List<String> list = exchange.getRequest().getHeaders().get("token");
            String token = list.get(0);
            if(token!=null){
                String userInfo = redisTemplate.opsForValue().get(token);
                if(userInfo!=null){
                    redisTemplate.expire(token,300,TimeUnit.SECONDS);
                    return chain.filter(exchange);
                }else{
                    Map<String,String> errorData=new HashMap<>();
                    errorData.put("msg","token失效");
                    errorData.put("code","900");
                    //说明Token失效，返回错误信息
                    return responseUNAUTHORIZED(exchange, JSON.toJSONString(errorData));
                }
            }else{
                //说明Token失效，返回错误信息
                Map<String,String> errorData=new HashMap<>();
                errorData.put("msg","token失效");
                errorData.put("code","900");
                //说明Token失效，返回错误信息
                return responseUNAUTHORIZED(exchange, JSON.toJSONString(errorData));
            }
        }
    }

    /**
     * 作者: LCG
     * 日期: 2021/6/25  16:41
     * 描述: 自定义返回信息，不在走后续请求流程
     * @Param [exchange, errorData]
     * @Return reactor.core.publisher.Mono<java.lang.Void>
     */
    public Mono<Void> responseUNAUTHORIZED(ServerWebExchange exchange,String errorData){
        ServerHttpResponse response = exchange.getResponse();
        byte[] bits = errorData.getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        response.setStatusCode(HttpStatus.OK);
        //指定编码，否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

}
